<template>
  <div class="demo-block">
    <!-- 组件展示区域 -->
    <div class="component-container">
      <component :is="componentName" v-if="componentName" v-bind="$attrs" />
    </div>
    <!-- 按钮区域 -->
    <div class="control-buttons">
      <CopySvg class="icon-svg"></CopySvg>
      <CodeSvg class="icon-svg" @click="expandEvent"></CodeSvg>
    </div>

    <!-- 代码展示区域 -->
    <div class="code-container" ref="codeContainerRef">
      <div class="language-vue">
        <div ref="highlightRef" class="highlight" v-html="decoded" />
      </div>
    </div>

    <!-- 固定区域 -->
    <transition name="collapse">
      <div v-show="isExpanded" class="fixed-control" @click="expandEvent">
        <span class="fixed-text">隐藏代码</span>
      </div>
    </transition>
  </div>
</template>

<script setup>
import CodeSvg from "./codeSvg.vue";
import CopySvg from "./copySvg.vue";
import { computed, ref, watch } from "vue";

const props = defineProps({
  componentName: String,
  source: String,
  componentSource: String,
});
const isExpanded = ref(false);

const highlightRef = ref();
const codeContainerRef = ref();

const decoded = computed(() => {
  return decodeURIComponent(props.source);
});

const componentSource = computed(() => {
  return decodeURIComponent(props.componentSource);
});

const codeAreaHeight = computed(() => highlightRef.value.clientHeight);

const expandEvent = () => (isExpanded.value = !isExpanded.value);

watch(isExpanded, (val) => {
  codeContainerRef.value.style.height = val ? `${codeAreaHeight.value + 1}px` : "0";
});
</script>

<style lang="scss" scoped>
.demo-block {
  margin: 10px 0;
  border: solid 1px var(--border-color);
  border-radius: 3px;
  transition: 0.2s;
}

.component-container {
  padding: 1.5rem;
  margin: 0.5px;
  background-color: var(--bg-color);
  border-bottom: 1px solid var(--border-color);
}

.code-container {
  position: relative;
  overflow: hidden;
  height: 0;
  transition: height 0.2s;
  background-color: var(--code-bg-color);
}

.control-buttons {
  padding: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  background-color: var(--bg-color);
  height: 44px;
  box-sizing: border-box;
}

.icon-svg {
  fill: var(--fill-color);
  transition: fill 0.2s ease-in;
  margin: 0 0.5rem;
  cursor: pointer;
}

.icon-svg:hover {
  fill: var(--fill-hover-color);
}

.fixed-control {
  display: flex;
  align-items: center;
  justify-content: center;
  border-top: 1px solid var(--border-color);
  height: 44px;
  box-sizing: border-box;
  background-color: var(--bg-color, #fff);
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
  margin-top: -1px;
  cursor: pointer;
  position: sticky;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  font-size: 14px;
}

.fixed-control:hover {
  .fixed-text {
    color: var(--fill-hover-color);
  }
}

.fixed-text {
  transition: color 0.2s ease-in;
  color: var(--fill-color);
}

.code-container {
  pre {
    margin-top: 0;
  }
}

// 折叠加隐藏过渡效果
.collapse-enter-active,
.collapse-leave-active {
  transition: all 0.2s;
  overflow: hidden;
}

.collapse-enter-from,
.collapse-leave-to {
  height: 0px !important;
  opacity: 0;
}
</style>
